近来看到chrome一个很geek的用法:一行代码,打造在线编辑器,试了一下发现挺有趣的。那我们在浏览器输入那一行的是什么呢?

其实从本质上,那不是什么代码、更不是什么网址,而是一个data URI。何为data URI?这又得从头讲起。

URI?URL?URN?域名?网址?

标题列举了几个名词,不细究地话,多数的互联网的使用者们还是容易分不清的。这几个东西有个共同点就是能通过浏览器输入并访问,而浏览器的输入框也确实能接收不少东西,其中最基本的功能便是让我们输入网址。所谓网址有两层含义,一是直接使用网站服务器的ip地址,以及便于记忆的域名,输入域名后浏览器会通过DNS获得该域名对应的ip地址。

但我们会发现,只输入网址后,浏览器会自动在其前面加上http或https:我们也会发现,我们访问的网站域名后面还会加上其他一些东西。因为网址只是个地址,而我们找到对方的服务器后,还要使用其服务、并进一步使用它的文件资源;使用什么服务由双方使用的应用协议如http决定,而使用该服务下的什么资源就需要我们能在浩如烟海的互联网中标定该资源及其位置,这就产生了URL(统一资源定位符)。

URL的格式由三部分组成:

scheme://host[:Port][/path]

依次指示了服务类型、主机、端口及资源路径,通过这样的方式全网资源的位置就都有了标记,我们只需在浏览器输入一段URL便能查看资源。当然URL的直接使用者多是程序员们,毕竟很多时候用户都不需要自己完整地输入URL,因为浏览器的历史记录、提示功能已经能相当迅速地判断我们要访问什么了。但作为互联网的使用者,每个人都应了解到,正因有了URL,我们才能方便地使用整个互联网丰富多彩的资源和服务。

扯了这么多,那URL和URI、URN,又是什么关系?其实很简单,URL既负责标识资源又要指示其位置,而URN只负责标识资源名字,同时URL和URN都是URI的两个子集,所以URI既可以是URL、URN中一种,也可以两者都是、都不是。总之,他们几个间最大的区别就是有无包含位置信息、有无包含资源名,比如一个磁力链接magnet:?xt=urn:btih:abcdef就是一个URN也是个URI,但却不是URL,因为不能通过它判断你要下载的文件到底在哪台服务器上。

data URI

现在,再来看看我们为改造chrome而输入的那一行,比如:

data:text/html, <html contenteditable>

可见其中并没有标识位置,也没有标识资源的名称,所以它就只是一个URI,具体来讲叫data URI。
其格式规定如下:

data:[<mime type>][;charset=<charset>][;base64],<encoded data>

<mime type>:要呈现的数据类型,默认text/plain
<charset>:使用的字符集,默认US-ASCII
base64:使用base64编码方式;没声明这个则使用URL编码,超过URL编码范围的字符将采用%xxx的十六进制编码

了解了data URI的原理后,回过头看一下实现在线编辑器的URI,我们就是使用了一个mime type为text/html的data URI。而在<encoded data>部分,你便可以使用html、javascript、css在一行小小的输入框里尽情码出你想要的效果,乃至实现一个有geek范的编辑器等单页面应用~

关于编码方式

字符进行编码主要是为了便于传输或者加密。在浏览器上对含有非标准字符的URL都会使用URL编码,即将一个字符转换为%加几位十六进制编码,比如js的encodeURI()encodeURIComponent()方法可实现这一功能。

至于上面提到的base64,简单来讲,这种编码方式使用64个字符进行数据编码,包括大小写英文字母、数字0~9、+、/。其特点就是把二进制数据编码为ASCII字符,同时相比URL编码这种十六进制编码方式,base64编码后的字符串长度更小,比如Nicholas在这篇文章里举了个例子,下面两个data URI标识了同一张图片:

data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub//ge
8WSLf/rhf/3kdbW1mxsbP//mf///yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1h
LnjM5UUde0ECwLJoExKcppV0aCcGCmTIHEIUEqjgaORCMxIC6e0CcguWw6aFjsVMkkIr7g
77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/gAwXEQA7

data:image/gif,GIF89a%22%00%1B%00%F7%00%00lll%D6%D6%D6%FF%EB%85
%FF%E0%7B%FF%F7%91%FF%D4o%DF%DF%DF%F6%F6%F6%87%87%87%FE
%CBf%FF%F4%8E%E6%B3NKKK%C5%92-%FF%FF%99%FF%FF%FF%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%2C%00%00
%00%00%22%00%1B%00%00%08%A9%00%1F%08%1CH%B0%A0%C1%83%08
%13*%5C%C8%B0%A1%C3%87%10%23J%9CH%91%60%83%8B%0D%0C%1C
%A8h%B0%81%C5%00%1B9%0A%F4%E8%A0%A4%83%07%181j%9C%D8%80
%80%82%97%2F%0B6%40%60%80%A5%00%01)s%AA%94%D8%60%80G%84
%02P%22%E0Y%A0%81%C9%A3%25%138h%00%80g%02%A3%04%A2J%8D
%BA%60i%D3%88%0D%9E%3A%B8%C9%95kU%A6N%8D%0E%18Kv%EC%D7
%AB%10%B3%1A-%C0%B6-%5B%A3%60%23%1A%D0I%97%C1%D0%88%07
%02%20%00%C0%B7%AF_%00%08%02L%3C%60%20%80%E1%C3%88%03
%AC%14%C9%B8%B1%E3%C7%90%23K%9EL0%20%00%3B

可以很明显看到Base64编码的字符串长度大大被压缩了,当然这只是相对URL编码这种十六进制编码方式看起来变短了,其实base64的算法会把原字符串中逐三字节拓为四字节,最终反倒是比原资源多出了三分之一的数据量。

data URI与性能

虽然用data URI来编写web应用是个十分geek的行为,但是除了这些,别忘了data URI的本来目的---让我们方便地用字符标记和传送web上的资源。如果我们在代码中使用data URI标识的资源,优势是data URI本身就被看成代码文件的一部分,相比每次用http请求加载资源要快;缺点则如上文所诉,其会一定程度地加大数据量。然而只要资源请求的数目远大于数据量的增加,在资源加载过程中避免耗时的http请求而节省的时间就能抵消掉数据量变大带来的影响,这对于那些请求的每个资源较小、但请求高频的web服务提升性能而言,是大有好处的。


Levon
526 声望89 粉丝

大自然爱好者